/**
 * 图形分割工具
 */
class SplitUtil {
  constructor(_tool) {
    this.tool = _tool;
    this.line = null;
    this.polygon = null;
  }

  /**
   * 开始分割
   * @param {*} polygon 待分割图形
   */
  start(polygon) {
    return new Promise((resolve) => {
      this.polygon = polygon;
      this.tool.events.onCreate = (e) => {
        this.line = e.features[0];
        var result = this.process();
        this.tool.events.onCreate = null;
        this.stop();
        resolve(result);
      };
      this.tool.changeMode('draw_line_string');
    });
  }

  /**
   * 停止分割
   */
  stop() {
    this.tool.reset();
  }

  /**
   * 切割算法
   * @param {LineString} line
   * @param {Polygon} polygon
   */
  process() {
    var intersectPoints = turf.lineIntersect(this.line, this.polygon).features;
    console.log('intersectPoints', intersectPoints);
    // 图上新增两个交点
    // drawTool.add(turf.featureCollection(intersectPoints));
    if (intersectPoints.length !== 2) {
      alert('线面交点必须为两个');
      return;
    }

    // 寻找交点与多边形形成的线的最近点，消除交点误差
    var polyline = turf.polygonToLineString(this.polygon);

    // 通过最近两个点，切割多边形线
    var slicedPolyline = turf.lineSlice(intersectPoints[0], intersectPoints[1], polyline);

    // 起点终点设置为交点位置
    slicedPolyline = this.adjustStartEnd(slicedPolyline, intersectPoints);
    console.log('slicedPolyline', slicedPolyline);

    // 找出切割出来的多边形线的点在多边形线的位置
    var foundedIndex = -1;
    slicedPolyline.geometry.coordinates.forEach((temp) => {
      if (foundedIndex === -1) {
        var idx = polyline.geometry.coordinates.indexOf(temp);
        if (idx >= 0) {
          foundedIndex = idx;
        }
      }
    });
    console.log('foundedIndex', foundedIndex);
    // eslint-disable-next-line init-declarations
    var newPolylineCoordinates;
    if (foundedIndex === -1) {
      // 两个交点在多边形的同一条边上
      // 取两个交点的中心点，以中心点作为起点和终点，拼接一个多边形，
      // 再以该多边形，做一次切割。

      // 中心点
      var midpoint = turf.midpoint(intersectPoints[0], intersectPoints[1]);

      // 取出多边形的所有线段
      var polylineSegments = turf.lineSegment(polyline).features;
      // 取出与中心点最近的线段
      var mindis = Number.MAX_VALUE;
      var closetIndex = null;
      polylineSegments.forEach((segment, index) => {
        var dis = turf.pointToLineDistance(midpoint, segment);
        if (dis < mindis) {
          mindis = dis;
          closetIndex = index;
        }
      });
      //  根据最近线段重新排序
      var sortedSegments = polylineSegments.slice(closetIndex).concat(polylineSegments.slice(0, closetIndex));
      console.log('sortedSegments', sortedSegments);
      var midpointCoordinates = midpoint.geometry.coordinates;
      newPolylineCoordinates = [midpointCoordinates]
        .concat(sortedSegments.map((segment) => segment.geometry.coordinates).flat())
        .concat([midpointCoordinates]);
    } else {
      // 根据切割后的某一点位置作为起点，重新生成多边形线
      var polylineCoordinates = JSON.parse(JSON.stringify(polyline.geometry.coordinates));
      // 移除最后一个点
      polylineCoordinates.pop();
      newPolylineCoordinates = polylineCoordinates.slice(foundedIndex)
        .concat(polylineCoordinates.slice(0, foundedIndex));
      newPolylineCoordinates.push(newPolylineCoordinates[0]);
    }
    var newPolyline = turf.lineString(newPolylineCoordinates);
    console.log('polyline coordinates ', polyline.geometry.coordinates);
    console.log('newPolyline coordinates ', newPolylineCoordinates);
    // 根据新的多边形线，再切割
    var newSlicedPolyline = turf.lineSlice(intersectPoints[0], intersectPoints[1], newPolyline);
    newSlicedPolyline = this.adjustStartEnd(newSlicedPolyline, intersectPoints);
    console.log('newSlicedPolyline', newSlicedPolyline);
    // 通过交点切割分割线
    var slicedSplitLine = turf.lineSlice(intersectPoints[0], intersectPoints[1], this.line);
    console.log('slicedSplitLine', slicedSplitLine);
    // merge lineto polyline
    var firstpolyon = this.mergeLine(slicedPolyline, slicedSplitLine);
    var secondpolygon = this.mergeLine(newSlicedPolyline, slicedSplitLine);
    console.log('firstpolyon', firstpolyon);
    console.log('secondpolygon', secondpolygon);
    return {
      line: this.line,
      polygon: this.polygon,
      polygons: [firstpolyon, secondpolygon]
    };
  }

  /**
   * 合并线
   * @param {feature} line1 线1
   * @param {feature} line2 线2
   */
  mergeLine(line1, line2) {
    var coordinates1 = line1.geometry.coordinates,
      coordinates2 = line2.geometry.coordinates;
    var start1 = coordinates1[0], start2 = coordinates2[0],
      finish2 = coordinates2[coordinates2.length - 1];
    var mergedCoordinates = [];
    if (
      turf.distance(turf.point(start1), turf.point(start2)) <
      turf.distance(turf.point(start1), turf.point(finish2))
    ) {
      // 线段1起点和线段2起点得距离 比 线段1起点和线段2终点得距离 近
      // 线段1拼接 反向线段2 （线段1起点->线段1终点->线段2终点->线段2起点->线段1起点）
      mergedCoordinates = [...coordinates1, ...coordinates2.reverse(), start1];
    } else {
      // 线段1拼接 线段2 （线段1起点->线段1终点->线段2起点->线段2终点->线段1起点）
      mergedCoordinates = [...coordinates1, ...coordinates2, start1];
    }
    return turf.polygon([mergedCoordinates]);
  }

  /**
   * 调整线的起点和终点
   * @param {feature} line 线
   * @param {Array} startend 起点和终点
   */
  adjustStartEnd(line, startend) {
    var coordinates = line.geometry.coordinates;
    var start = startend[0],
      end = startend[1];
    var linefirst = coordinates[0],
      linelast = coordinates[coordinates.length - 1];
    if (turf.distance(start, turf.point(linefirst)) < turf.distance(start, turf.point(linelast))) {
      coordinates[0] = start.geometry.coordinates;
      coordinates[coordinates.length - 1] = end.geometry.coordinates;
    } else {
      coordinates[0] = end.geometry.coordinates;
      coordinates[coordinates.length - 1] = start.geometry.coordinates;
    }
    return turf.lineString(coordinates);
  }
}

export default SplitUtil;
